package com.giraffe.aiochat.server.handler;

import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.giraffe.aiochat.model.User;
import com.giraffe.aiochat.server.manager.ClientManager;

public class ReadCompletionHandler implements CompletionHandler<Integer, ByteBuffer> {
    private static final Logger logger = LoggerFactory.getLogger(ReadCompletionHandler.class);
    private final AsynchronousSocketChannel clientChannel;
    private final MessageHandler messageHandler;
    private final ClientManager clientManager = ClientManager.getInstance();

    public ReadCompletionHandler(AsynchronousSocketChannel clientChannel) {
        this.clientChannel = clientChannel;
        this.messageHandler = new MessageHandler();
    }

    @Override
    public void completed(Integer bytesRead, ByteBuffer buffer) {
        if (bytesRead > 0) {
            buffer.flip();
            String jsonStr = new String(buffer.array(), 0, bytesRead);
            messageHandler.handleMessage(jsonStr, clientChannel);
            buffer.clear();
            clientChannel.read(buffer, buffer, this);
        } else if (bytesRead == -1) {
            logger.info("Client disconnected: {}", clientManager.getNickname(clientChannel));
            closeChannel();
        }
    }

    @Override
    public void failed(Throwable exc, ByteBuffer buffer) {
        logger.error("Read operation failed", exc);
        closeChannel();
    }

    private void closeChannel() {
        User user = clientManager.removeClient(clientChannel);
        if (user != null) {
            messageHandler.handleLeave(user.getName(), clientChannel);    
        }
    }
}